package midend.IR_Instruction;

import midend.IR_Type.IR_Const;
import midend.IR_Type.IR_Type;
import midend.IR_Value.IR_BaseBlock;
import midend.IR_Value.IR_FuncBlock;
import midend.IR_Value.IR_Local_Value;
import midend.IR_Value.IR_Value;

import java.util.ArrayList;
import java.util.List;

public class Type_Trans_Instruction extends Instruction{
    IR_Value origin,res;
    int Trans_Type;
    public Type_Trans_Instruction(List<IR_Value> op, IR_BaseBlock bb,int z) {
        super(op, bb);
        this.origin = get_op().get(1);
        this.res = get_op().get(0);
        this.Trans_Type = z;
        addValue(origin);
    }
    public void updateop(int index, IR_Value newValue) {
        if(index == 0){
            set_Origin(newValue);
            set_Op(index + 1, newValue);
        }
    }
    public int get_Trans_Type() {
        return Trans_Type;
    }

    public void set_Origin(IR_Value origin) {
        set_Op(1, origin);
        this.origin = origin;
    }

    public void set_Res(IR_Value res) {
        this.res = res;
        set_Op(0,res);
    }

    public IR_Value res() {
        return res;
    }

    public IR_Value origin() {
        return origin;
    }

    @Override
    public String toString() {
        //op [new old]
        // 0
        if(Trans_Type == IR_Const.IntToFloat){
            return res.get_ValueName() + " = sitofp i32 " + origin.get_ValueName() + " to float";
        }
        // 1
        else if (Trans_Type == IR_Const.FloatToInt){
            return res.get_ValueName() + " = fptosi float " + origin.get_ValueName() + " to i32";
        }
        else if (Trans_Type == IR_Const.BITCAST){
            return res.get_ValueName() + " = bitcast float* " + origin.get_ValueName() + " to i32*";
        }
        return null;
    }

    @Override
    public Type_Trans_Instruction clone(IR_BaseBlock block) {
        String copy_name = ((IR_Local_Value) get_op().get(0)).get_Local_Identity();
        IR_Type copy_type = get_op().get(0).get_Type();
        IR_Value res = new IR_Local_Value(copy_name, copy_type);
        ArrayList<IR_Value> copy_ops = new ArrayList<>();
        copy_ops.add(res);
        for (int i = 1 ; i< get_op().size() ; i++) {
            IR_Value copy_op  = get_op().get(i);
            if(IR_FuncBlock.cloneMap_Value.containsKey(copy_op)) {
                copy_op = IR_FuncBlock.cloneMap_Value.get(copy_op);
            }
            copy_ops.add(copy_op);
        }
        Type_Trans_Instruction copy_ins = new Type_Trans_Instruction(copy_ops, block, Trans_Type);
        return copy_ins;
    }

}
